home *** CD-ROM | disk | FTP | other *** search
- char *tipx_rev = "x1.21";
- #define PATCHLEVEL 1
- /*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- /*
- * Modifications by Warren Tucker <wht%n4hgf.uucp@emory.mathcs.emory.edu>
- * for eight-bit transparent pass through and file transfer protocols
- * are unencumbered in any way. They are yours, ours, everybody's, nobody's.
- */
- /*+:EDITS:*/
- /*:05-08-1990-15:05-wht@n4hgf-rawthru */
- /*:05-08-1990-15:00-wht@n4hgf-move tip.c original to tip-orig.c */
-
- #ifndef lint
- char copyright[] =
- "@(#) Copyright(c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
- #endif /* not lint */
-
- #ifndef lint
- static char sccsid[] = "@(#)tip.c 5.8 (Berkeley) 9/2/88 (mod by wht@n4hgf)";
- #endif /* not lint */
-
- /*
- * tip - UNIX link to other systems
- * tip [-psv] [-speed] system-name [data]
- * or
- * cu phone-number [-s speed] [-l line] [-a acu]
- */
- #include "tip.h"
-
- /*
- * Baud rate mapping table
- */
- int bauds[] =
- {
- 0,50,75,110,134,150,200,300,600,
- 1200,1800,2400,4800,9600,19200,38400,-1
- };
-
- #ifdef TIPX
- int rawthru = 0;
- char *rawthru_msg = "\r\n--> raw tip: 3 ~ rapidly for ~ equivalent\r\n";
- char *no_rawthru_msg = "\r\n--> normal tip: 1 ~ == ~\r\n";
- extern char opened_tty[];
- #endif
-
- int page;
- int disc = OTTYDISC; /* tip normally runs this way */
- sigfunc_t intprompt();
- sigfunc_t timeout();
- sigfunc_t cleanup();
- char *login();
- char *sname();
- char PNbuf[256]; /* This limits the size of a number */
- struct sgttyb ttyarg;
-
- #ifdef TIPX
- typedef struct b_to_br
- {
- char *baud_rate;
- int B_code;
- } B_TO_BR;
-
- B_TO_BR speeds[] = /* ordered to put less common rates later in table */
- { /* and the vagaries of baud rates above 9600 "handled" */
- "2400", B2400,
- "1200", B1200,
- "9600", B9600,
- #if defined(B19200)
- "19200",B19200,
- #endif
- #if defined(B38400)
- "38400",B38400,
- #endif
- "4800", B4800,
- "300", B300,
- "110", B110,
- "600", B600,
- "75", B75,
- "50", B50,
- "HUP", B0,
- "EXTA", EXTA,
- "EXTB", EXTB,
-
- (char *)0,0
- };
- #endif /* TIPX */
-
- /*+-------------------------------------------------------------------------
- B_to_baud_rate(code) - convert CBAUD B_ code to baud rate string
- --------------------------------------------------------------------------*/
- #ifdef TIPX
- char *
- B_to_baud_rate(code)
- int code;
- {
- register int n;
-
- for(n=0; speeds[n].baud_rate; n++)
- if(speeds[n].B_code == code)
- return(speeds[n].baud_rate);
- return("-----");
- } /* end of B_to_baud_rate */
- #endif /* TIPX */
-
- main(argc,argv)
- char *argv[];
- {
- int uuid;
- char *system = NOSTR;
- char *data = NOSTR;
- register int i;
- register char *p;
- char sbuf[12];
-
- uid = getuid();
- gid = getgid();
- euid = geteuid(); /* should be root */
- egid = getegid();
- uuid = getuucpuid();
-
- if(equal(sname(argv[0]),"cu"))
- {
- setreuid(uid,uuid);
- cumode = 1;
- cumain(argc,argv);
- goto cucommon;
- }
-
- if(argc < 2)
- {
- fprintf(stderr,"usage: tip [-psv] [-speed] [system-name] [data]\n");
- exit(1);
- }
-
- for(; argc > 1; argv++,argc--)
- {
- if(argv[1][0] != '-')
- {
- if(system)
- data = argv[1];
- else
- system = argv[1];
- }
- else switch(argv[1][1])
- {
-
- case 'p':
- page++;
- break;
- case 's':
- slip++;
- break;
- case 'v':
- vflag++;
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- BR = atoi(&argv[1][1]);
- break;
-
- default:
- fprintf(stderr,"tip: %s, unknown option\n",argv[1]);
- break;
- }
- }
- if(!isatty(0) && !slip && !page)
- {
- fprintf(stderr,"tip: warning: input is not a tty\n");
- }
- if(slip)
- {
- setreuid(euid,uuid);
- uid = 0;
- }
- else
- {
- setreuid(uid,uuid);
- }
- euid = uuid;
-
- if(system == NOSTR)
- goto notnumber;
- if(isalpha(*system))
- goto notnumber;
- /*
- * System name is really a phone number...
- * Copy the number then stomp on the original (in case the number
- * is private, we don't want 'ps' or 'w' to find it).
- */
- if(strlen(system) > sizeof PNbuf - 1)
- {
- fprintf(stderr,"tip: phone number too long (max = %d bytes)\n",
- sizeof PNbuf - 1);
- exit(1);
- }
- strncpy( PNbuf,system,sizeof PNbuf - 1 );
- for(p = system; *p; p++)
- *p = '\0';
- PN = PNbuf;
- (void)sprintf(sbuf,"tip%d",BR);
- system = sbuf;
-
- notnumber:
- signal(SIGINT,cleanup);
- signal(SIGQUIT,cleanup);
- signal(SIGHUP,cleanup);
- signal(SIGTERM,cleanup);
- signal(SIGPIPE,cleanup);
-
- if((i = hunt(system)) == 0)
- {
- printf("all ports busy\n");
- exit(3);
- }
- if(i == -1)
- {
- printf("link down\n");
- (void)uu_unlock(uucplock);
- exit(3);
- }
- setbuf(stdout,NULL);
- loginit();
-
- /*
- * Kludge, their's no easy way to get the initialization
- * in the right order, so force it here
- */
- if((PH = getenv("PHONES")) == NOSTR)
- PH = "/etc/phones";
- vinit(); /* init variables */
- setparity("none"); /* set the parity table */
- if((i = speed(number(value(BAUDRATE)))) == NULL)
- {
- printf("tip: bad baud rate %d\n",number(value(BAUDRATE)));
- (void)uu_unlock(uucplock);
- exit(3);
- }
-
- if(slip)
- {
- if(SA == NOSTR)
- {
- printf("tip: local addr not set\n");
- uu_unlock(uucplock);
- exit(3);
- }
- if(DA == NOSTR)
- {
- printf("tip: destination addr not set\n");
- uu_unlock(uucplock);
- exit(3);
- }
- if(SM == NOSTR)
- {
- printf("tip: slip netmask not set\n");
- uu_unlock(uucplock);
- exit(3);
- }
- }
-
- /*
- * Now that we have the logfile and the ACU open
- * return to the real uid and gid. These things will
- * be closed on exit. Swap real and effective uid's
- * so we can get the original permissions back
- * for removing the uucp lock.
- */
- user_uid(); /* in the case of slip, we are now priviliged */
-
- /*
- * Hardwired connections require the
- * line speed set before they make any transmissions
- * (this is particularly true of things like a DF03-AC)
- */
- if(HW)
- ttysetup(i);
- if(p = lconnect())
- {
- printf("\07%s\n[EOT]\n",p);
- daemon_uid();
- (void)uu_unlock(uucplock);
- exit(1);
- }
- if(!HW)
- ttysetup(i);
-
-
- if(LS != NOSTR)
- {
- fprintf(stderr,"\07[Logging in...]\r\n");
- if(p = login())
- {
- printf("\07%s\n[EOT]\n",p);
- daemon_uid();
- (void)uu_unlock(uucplock);
- exit(1);
- }
- }
-
- if(page)
- {
- i = sendpage(data);
- daemon_uid();
- (void)uu_unlock(uucplock);
- exit(i);
- }
-
- if(slip)
- {
- i = runslip();
- daemon_uid();
- (void)uu_unlock(uucplock);
- exit(i);
- }
-
- cucommon:
- /*
- * From here down the code is shared with
- * the "cu" version of tip.
- */
-
- ioctl(0,TIOCGETP,(char *)&defarg);
- ioctl(0,TIOCGETC,(char *)&defchars);
- ioctl(0,TIOCGLTC,(char *)&deflchars);
- ioctl(0,TIOCGETD,(char *)&odisc);
- arg = defarg;
- #ifdef TIPX
- arg.sg_flags = CBREAK;
- #else
- arg.sg_flags = ANYP | CBREAK;
- #endif
- tchars = defchars;
- tchars.t_intrc = tchars.t_quitc = -1;
- ltchars = deflchars;
- ltchars.t_suspc = ltchars.t_dsuspc = ltchars.t_flushc
- = ltchars.t_lnextc = -1;
- raw();
-
- pipe(fildes);
- pipe(repdes);
- signal(SIGALRM,timeout);
-
- /*
- * Everything's set up now:
- * connection established (hardwired or dialup)
- * line conditioned (baud rate, mode, etc.)
- * internal data structures (variables)
- * so, fork one process for local side and one for remote.
- */
- #ifdef TIPX
- printf("tipx (tip 4.3 mod by wht@n4hgf %s.%02d) connected to %s\r\n",
- tipx_rev,PATCHLEVEL,opened_tty);
- fputs("Copyright (c) 1983 The Regents of the University of California.\r\n",
- stdout);
- printf("line speed = %s, tandem = %s\r\n",
- B_to_baud_rate(ttyarg.sg_ospeed),
- (ttyarg.sg_flags & TANDEM) ? "yes" : "no");
- #else
- printf(cumode ? "Connected\r\n" : "\07connected\r\n");
- #endif
- if(pid = fork())
- tipin();
- else
- tipout();
- /*NOTREACHED*/
- }
-
- sigfunc_t
- cleanup()
- {
-
- daemon_uid();
- (void)uu_unlock(uucplock);
- if(pid)
- {
- (void) kill(pid,SIGTERM);
- unraw();
- }
- else if(odisc)
- ioctl(0,TIOCSETD,(char *)&odisc);
- exit(0);
- }
-
- /*
- * Muck with user ID's. We are setuid to the owner of the lock
- * directory when we start. user_uid() reverses real and effective
- * ID's after startup, to run with the user's permissions.
- * daemon_uid() switches back to the privileged uid for unlocking.
- * Finally, to avoid running a shell with the wrong real uid,
- * shell_uid() sets real and effective uid's to the user's real ID.
- */
- static int uidswapped;
-
- user_uid()
- {
- if(uidswapped == 0)
- {
- setregid(egid,gid);
- setreuid(euid,uid);
- uidswapped = 1;
- }
- }
-
- daemon_uid()
- {
- if(uidswapped)
- {
- setreuid(uid,euid);
- setregid(gid,egid);
- uidswapped = 0;
- }
- }
-
- shell_uid()
- {
-
- setreuid(uid,uid);
- setregid(gid,gid);
- }
-
- /*
- * put the controlling keyboard into raw mode
- */
- raw()
- {
-
- ioctl(0,TIOCSETP,&arg);
- ioctl(0,TIOCSETC,&tchars);
- ioctl(0,TIOCSLTC,<chars);
- ioctl(0,TIOCSETD,(char *)&disc);
- }
-
-
- /*
- * return keyboard to normal mode
- */
- unraw()
- {
-
- ioctl(0,TIOCSETD,(char *)&odisc);
- ioctl(0,TIOCSETP,(char *)&defarg);
- ioctl(0,TIOCSETC,(char *)&defchars);
- ioctl(0,TIOCSLTC,(char *)&deflchars);
- }
-
- static jmp_buf promptbuf;
-
- /*
- * Print string ``s'', then read a string
- * in from the terminal. Handles signals & allows use of
- * normal erase and kill characters.
- */
- prompt(s,p)
- char *s;
- register char *p;
- {
- register char *b = p;
- sigfunc_t(*oint)(),(*oquit)();
-
- stoprompt = 0;
- oint = signal(SIGINT,intprompt);
- oquit = signal(SIGQUIT,SIG_IGN);
- unraw();
- printf("%s",s);
- if(setjmp(promptbuf) == 0)
- while((*p = getchar()) != EOF && *p != '\n')
- p++;
- *p = '\0';
-
- raw();
- signal(SIGINT,oint);
- signal(SIGQUIT,oint);
- return(stoprompt || p == b);
- }
-
- /*
- * Interrupt service routine during prompting
- */
- sigfunc_t
- intprompt()
- {
-
- signal(SIGINT,SIG_IGN);
- stoprompt = 1;
- printf("\r\n");
- longjmp(promptbuf,1);
- }
-
- /*
- * ****TIPIN TIPIN****
- */
- tipin()
- {
- char gch,bol = 1;
-
- /*
- * Kinda klugey here...
- * check for scripting being turned on from the .tiprc file,
- * but be careful about just using setscript(), as we may
- * send a SIGEMT before tipout has a chance to set up catching
- * it; so wait a second, then setscript()
- */
- if(boolean(value(SCRIPT)))
- {
- sleep(1);
- setscript();
- }
-
- #ifdef TIPX
- if(!rawthru)
- goto NORMAL_TIP2;
-
- RAWTHRU_TIP:
- printf(rawthru_msg);
- while(1)
- {
- long count;
- char chbuf[4];
- read(0,&gch,1);
- if((gch == character(value(ESCAPE))))
- {
- sleep(1);
- ioctl(0,FIONREAD,&count);
- if(count == 2)
- { /* might have raw mode escape */
- read(0,chbuf,2);
- if((chbuf[0] == character(value(ESCAPE))) &&
- (chbuf[1] == character(value(ESCAPE))))
- {
- printf("rawthru%s",ctrl(chbuf[0]));
- if(!(gch = escape()))
- {
- if(!rawthru)
- {
- bol = 1;
- goto NORMAL_TIP;
- }
- continue;
- }
- }
- else
- {
- gch = character(value(ESCAPE));
- write(FD,&gch,1);
- write(FD,chbuf,2);
- continue;
- }
- }
- }
- write(FD,&gch,1);
- }
-
- NORMAL_TIP:
- printf(no_rawthru_msg);
- NORMAL_TIP2:
- #endif /* TIPX */
- while(1)
- {
- gch = getchar()&0177;
- if((gch == character(value(ESCAPE))) && bol)
- {
- if(!(gch = escape()))
- #ifdef TIPX
- {
- if(rawthru)
- goto RAWTHRU_TIP;
- continue;
- }
- #else /* TIPX */
- continue;
- #endif /* TIPX */
- }
- else if(!cumode && gch == character(value(RAISECHAR)))
- {
- boolean(value(RAISE)) = !boolean(value(RAISE));
- continue;
- }
- else if(gch == '\r')
- {
- bol = 1;
- pwrite(FD,&gch,1);
- if(boolean(value(HALFDUPLEX)))
- printf("\r\n");
- continue;
- }
- else if(!cumode && gch == character(value(FORCE)))
- gch = getchar()&0177;
- bol = any(gch,value(EOL));
- if(boolean(value(RAISE)) && islower(gch))
- gch = toupper(gch);
- pwrite(FD,&gch,1);
- if(boolean(value(HALFDUPLEX)))
- printf("%c",gch);
- }
- }
-
- /*
- * Escape handler --
- * called on recognition of ``escapec'' at the beginning of a line
- */
- escape()
- {
- register char gch;
- register esctable_t *p;
- char c = character(value(ESCAPE));
- extern esctable_t etable[];
-
- gch = (getchar()&0177);
- for(p = etable; p->e_char; p++)
- if(p->e_char == gch)
- {
- if((p->e_flags&PRIV) && uid)
- continue;
- #ifdef TIPX
- if(!rawthru)
- #endif
- printf("%s",ctrl(c));
- (*p->e_func)(gch);
- return(0);
- }
- /* ESCAPE ESCAPE forces ESCAPE */
- if(c != gch)
- pwrite(FD,&c,1);
- return(gch);
- }
-
- speed(n)
- int n;
- {
- register int *p;
-
- for(p = bauds; *p != -1; p++)
- if(*p == n)
- return(p - bauds);
- return(NULL);
- }
-
- any(c,p)
- register char c,*p;
- {
- while(p && *p)
- if(*p++ == c)
- return(1);
- return(0);
- }
-
- size(s)
- register char *s;
- {
- register int i = 0;
-
- while(s && *s++)
- i++;
- return(i);
- }
-
- char *
- interp(s)
- register char *s;
- {
- static char buf[256];
- register char *p = buf,c,*q;
-
- while(c = *s++)
- {
- for(q = "\nn\rr\tt\ff\033E\bb"; *q; q++)
- if(*q++ == c)
- {
- *p++ = '\\';
- *p++ = *q;
- goto next;
- }
- if(c < 040)
- {
- *p++ = '^';
- *p++ = c + 'A'-1;
- }
- else if(c == 0177)
- {
- *p++ = '^';
- *p++ = '?';
- }
- else
- *p++ = c;
- next:
- ;
- }
- *p = '\0';
- return(buf);
- }
-
- char *
- ctrl(c)
- char c;
- {
- static char s[3];
-
- if(c < 040 || c == 0177)
- {
- s[0] = '^';
- s[1] = c == 0177 ? '?' : c+'A'-1;
- s[2] = '\0';
- }
- else
- {
- s[0] = c;
- s[1] = '\0';
- }
- return(s);
- }
-
- /*
- * Help command
- */
- help(c)
- char c;
- {
- register esctable_t *p;
- extern esctable_t etable[];
-
- printf("%c\r\n",c);
- for(p = etable; p->e_char; p++)
- {
- if((p->e_flags&PRIV) && uid)
- continue;
- printf("%2s",ctrl(character(value(ESCAPE))));
- printf("%-2s %c %s\r\n",ctrl(p->e_char),
- p->e_flags&EXP ? '*': ' ',p->e_help);
- }
- }
-
- /*
- * Set up the "remote" tty's state
- */
- ttysetup(speed)
- int speed;
- {
- unsigned bits = LDECCTQ;
-
- ttyarg.sg_ispeed = ttyarg.sg_ospeed = speed;
- ttyarg.sg_flags = RAW;
- if(boolean(value(TAND)))
- ttyarg.sg_flags |= TANDEM;
- if(boolean(value(DTRHUP)))
- {
- ioctl(FD,TIOCSDTR,0);
- ioctl(FD,TIOCHPCL,0);
- }
- ioctl(FD,TIOCSETP,(char *)&ttyarg);
- ioctl(FD,TIOCLBIS,(char *)&bits);
- }
-
- /*
- * Return "simple" name from a file name,
- * strip leading directories.
- */
- char *
- sname(s)
- register char *s;
- {
- register char *p = s;
-
- while(*s)
- if(*s++ == '/')
- p = s;
- return(p);
- }
-
- static char partab[0200];
-
- /*
- * Do a write to the remote machine with the correct parity.
- * We are doing 8 bit wide output, so we just generate a character
- * with the right parity and output it.
- */
- pwrite(fd,buf,n)
- int fd;
- char *buf;
- register int n;
- {
- register int i;
- register char *bp;
- extern int errno;
- #ifdef TIPX
- extern int rawthru;
-
- if(rawthru)
- {
- write(fd,buf,n);
- return;
- }
- #endif /* TIPX */
-
- bp = buf;
- for(i = 0; i < n; i++)
- {
- *bp = partab[(*bp) & 0177];
- bp++;
- }
- if(write(fd,buf,n) < 0)
- {
- if(errno == EIO)
- abort("Lost carrier.");
- /* this is questionable */
- perror("write");
- }
- }
-
- /*
- * Build a parity table with appropriate high-order bit.
- */
- setparity(defparity)
- char *defparity;
- {
- register int i;
- char *parity;
- extern char evenpartab[];
-
- if(value(PARITY) == NOSTR)
- value(PARITY) = defparity;
- parity = value(PARITY);
- for(i = 0; i < 0200; i++)
- partab[i] = evenpartab[i];
- if(equal(parity,"even"))
- return;
- if(equal(parity,"odd"))
- {
- for(i = 0; i < 0200; i++)
- partab[i] ^= 0200; /* reverse bit 7 */
- return;
- }
- if(equal(parity,"none") || equal(parity,"zero"))
- {
- for(i = 0; i < 0200; i++)
- partab[i] &= ~0200; /* turn off bit 7 */
- return;
- }
- if(equal(parity,"one"))
- {
- for(i = 0; i < 0200; i++)
- partab[i] |= 0200; /* turn on bit 7 */
- return;
- }
- fprintf(stderr,"%s: unknown parity value\n",PA);
- fflush(stderr);
- }
-
- /* The uid could be determined by stat()-ing ACULOG */
- getuucpuid()
- {
- struct passwd *pw;
-
- if((pw = getpwnam("uucp")) == NULL)
- {
- fprintf(stderr,"tip: unable to get uucp uid\n");
- exit(1);
- }
- return(pw->pw_uid);
- }
-